using Infrastructure.Attribute;
using Infrastructure.Extensions;
using System.Linq.Expressions;
using Infrastructure;
using Microsoft.AspNetCore.Mvc;
using Infrastructure.Filters;
using Mapster;
using ZR.Repository;
using ZR.Service.BaseFrame.IService;
using ZR.Model.BaseFrame.Dto;
using ZR.Model.BaseFrame.Entity;
using ZR.Model.Enums;

namespace ZR.Service.BaseFrame.Service
{

    /// <summary>
    /// 数据字典服务基类
    /// </summary>
    public class DataDicServiceBase : BaseService<DataDicEntity>
    {

            /// <summary>
            /// 添加数据字典
            /// </summary>
            /// <param name="model"></param>
            /// <returns></returns>
            public virtual async Task<bool> AddDataDic(DataDicEntity model)
            {
                    return await Insertable(model).ExecuteCommandIdentityIntoEntityAsync();
            }

            /// <summary>
            /// 修改数据字典
            /// </summary>
            /// <param name="model"></param>
            /// <returns></returns>
            public virtual async Task<bool> ModifyDataDic(DataDicEntity model)
            {
                    Expression<Func<DataDicEntity, object>> upColsExpr = m => new
                    {
                            m.PaDataDicId,
                            m.DataDicId,
                            m.DataName,
                            m.DataCode,
                            m.SortNo,
                            m.Remark,
                            m.ModifyTime,
                            m.ModifierId,
                            m.Modifier,
                            m.StateCode,
                    };
                    return await UpdateAsync(model, upColsExpr);
            }

            /// <summary>
            /// 删除数据字典
            /// </summary>
            /// <param name="ids"></param>
            /// <param name="isRealDel"></param>
            /// <returns></returns>
            public virtual async Task<bool> DeleteDataDic(long[] ids, bool isRealDel = true)
            {
                    var isOk = false;
                    if (isRealDel)
                    {
                            isOk = await Deleteable().Where(m => ids.Contains(m.DataDicId)).ExecuteCommandHasChangeAsync();
                    }
                    else
                    {
                            isOk = await Updateable().SetColumns(m => new DataDicEntity
                            {
                                    StateCode = DataStateEnum.Deleted.ToEnumCode(),
                                    Modifier = App.HttpContext.GetName(),
                                    ModifierId = App.HttpContext.GetUId(),
                                    ModifyTime = DateTime.Now,
                            })
                            .Where(m => ids.Contains(m.DataDicId))
                            .ExecuteCommandHasChangeAsync();
                    }
                    return isOk;
            }

            /// <summary>
            /// 变更数据字典状态
            /// </summary>
            /// <param name="req"></param>
            /// <returns></returns>
            public virtual async Task<bool> ChangeDataDicState([FromBody] ChangeDataDicStateReq req)
            {
                    var stateEnum = req.StateEnum;
                    if (stateEnum == null)
                    {
                            throw new CustomException(ResultCode.PARAM_ERROR);
                    }
                    var isOk = await Updateable().SetColumns(m => new DataDicEntity
                    {
                            StateCode = stateEnum.ToEnumCode(),
                            Modifier = App.HttpContext.GetName(),
                            ModifierId = App.HttpContext.GetUId(),
                            ModifyTime = DateTime.Now,
                    })
                    .Where(m => m.DataDicId == req.Id)
                    .ExecuteCommandHasChangeAsync();
                    return isOk;
            }

            /// <summary>
            /// 获取数据字典树选择列表
            /// </summary>
            /// <param name="req"></param>
            /// <returns></returns>
            public virtual async Task<List<TreeNodeInfo>> GetDataDicTreeSelectList(GetDataDicTreeSelectListReq req)
            {
                    var list=await Repository
                            .WhereIF(req.OnlyLevel1Node,m=>m.PaDataDicId==0)
                            .Where(m=>m.StateCode!=DataStateEnum.Deleted.ToEnumCode())
                            .Select(m => new TreeNodeInfo
                            {
                                    Id = m.DataDicId.ToString(),
                                    PaId = m.PaDataDicId.ToString(),
                                    Label=m.DataName
                            })
                            .ToListAsync();
                    if (req.IsReturnRoot)
                    {
                            list.Add(new TreeNodeInfo
                            {
                                    Id = "0",
                                    Label = string.IsNullOrWhiteSpace(req.RootNodeName)?"所有数据字典":req.RootNodeName,
                                    PaId = "-1"
                            });
                    }
                    var treeList=BuildTree(list);
                    return treeList;
            }
            /// <summary>
            /// 获取数据字典分页列表
            /// </summary>
            /// <param name="req"></param>
            /// <returns></returns>
            public virtual async Task<PagedInfo<DataDicListItemDto>> GetDataDicPageList(GetDataDicPageListReq req)
            {
                    string pathStr=null;
                    if(req.TreeNodeId>=0)
                    {
                            pathStr= $"/{req.TreeNodeId}/";
                    }
                    var filterExp=PageListFilterExp(req);
                
                    var result = await Repository.Context.Queryable<DataDicEntity>()
                                .LeftJoin<DataDicEntity>((m,n)=>m.PaDataDicId==n.DataDicId)
                                .Where(filterExp.ToExpression())
                                .WhereIF(req.TreeNodeId>=0,m=>m.PaDataDicId==req.TreeNodeId)
                                .WhereIF(!string.IsNullOrEmpty(req.Keywords), 
                                    m => 
                                        m.DataName.Contains(req.Keywords)
                                        || m.DataCode.Contains(req.Keywords)
                                )
                                .Where(m=>m.StateCode!=DataStateEnum.Deleted.ToEnumCode())
                                .OrderBy(m=>m.DataDicId,OrderByType.Desc)
                    
                                .Select((m,n)=>new DataDicListItemDto
                                {
                                        PaDataDicId=m.PaDataDicId,
                                        PaDataName=n.DataName,
                                        DataDicId=m.DataDicId,
                                        DataName=m.DataName,
                                        DataCode=m.DataCode,
                                        SortNo=m.SortNo,
                                        Remark=m.Remark,
                                        CreateTime=m.CreateTime,
                                        Creater=m.Creater,
                                        StateCode=m.StateCode,
                                })
                    .ToPageAsync(req);
                    return result;
        }

        /// <summary>
        /// 分页列表过滤表达式
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        private static Expressionable<DataDicEntity> PageListFilterExp(GetDataDicPageListReq req)
        {
                var predicate = Expressionable.Create<DataDicEntity>();

                predicate = predicate.AndIF(!string.IsNullOrEmpty(req.StateCode), m => m.StateCode == req.StateCode);
                return predicate;
        }

        /// <summary>
        /// 获取数据字典详情
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public virtual async Task<DataDicDetailDto> GetDataDicDetail(long id)
        {
                var detail = await Queryable()
                    .Where(x => x.DataDicId == id)
                    .FirstAsync();
                var result = detail.Adapt<DataDicDetailDto>();
                return result;
        }

    }
}